package org.geometerplus.zlibrary.text.view;

import android.text.TextUtils;
import android.util.Pair;

import com.chineseall.reader.ui.ReadActivity;
import com.chineseall.reader.ui.util.ReadSettingUtil;
import com.chineseall.reader.ui.view.readmenu.ReadStyle;
import com.chineseall.readerapi.beans.BookReadNote;
import com.chineseall.readerapi.beans.INoteBean;
import com.chineseall.readerapi.beans.LocalDumpNote;
import com.chineseall.readerapi.entity.Chapter;
import com.iwanvi.common.utils.LogUtil;

import org.geometerplus.fbreader.fbreader.FBReaderApp;
import org.geometerplus.zlibrary.core.util.ZLColor;
import org.geometerplus.zlibrary.core.view.SelectionCursor;
import org.geometerplus.zlibrary.core.view.ZLPaintContext;

import java.util.LinkedList;
import java.util.List;

/**
 * 笔记数据
 * Created by huangyx on 2016.3.21.
 */
public class NotesData {

    private static NotesData sInstance;

    public synchronized static NotesData instance() {
        if (sInstance == null) {
            sInstance = new NotesData();
        }
        return sInstance;
    }

    private List<ZLTextSelection> mViewNotes;
    private ZLColor bgColor;


    private NotesData() {
        mViewNotes = new LinkedList<ZLTextSelection>();
        bgColor = new ZLColor(0);
    }

    public void loadZLSelectionData(ZLTextView zlTextView, List<BookReadNote> notes, List<LocalDumpNote> localNotes) {
        synchronized (mViewNotes) {
            mViewNotes.clear();
            for (BookReadNote note : notes) {
                ZLTextSelection selection = new ZLTextSelection(zlTextView, note);
                mViewNotes.add(selection);
            }
            for (LocalDumpNote note : localNotes) {
                ZLTextSelection selection = new ZLTextSelection(zlTextView, note);
                mViewNotes.add(selection);
            }
        }
    }

    public boolean doDeleteNewNote(BookReadNote note) {
        synchronized (mViewNotes) {
            if (note == null) {
                return false;
            }
            ZLTextSelection deleteSelection = null;
            for (ZLTextSelection selection : mViewNotes) {
                if (selection.getNoteData() != null && selection.getNoteData().equals(note)) {
                    deleteSelection = selection;
                    break;
                }
            }

            if (deleteSelection != null) {
                LogUtil.d("Note", "删除笔记:" + (note).bookContent + " deleteSelection != null");
                mViewNotes.remove(deleteSelection);
                return true;
            }
            return false;
        }
    }

    public boolean doAddNewNote(ZLTextView myView, BookReadNote note) {
        if (note == null) {
            return false;
        }
        synchronized (mViewNotes) {
            ZLTextSelection selection = new ZLTextSelection(myView, note);
            if (selection != null) {
                mViewNotes.remove(selection);
                return mViewNotes.add(selection);
            }
            return false;
        }
    }

    public boolean doAddNewNote(ZLTextView myView, LocalDumpNote note) {
        if (note == null) {
            return false;
        }
        synchronized (mViewNotes) {
            ZLTextSelection selection = new ZLTextSelection(myView, note);
            if (selection != null) {
                mViewNotes.remove(selection);
                return mViewNotes.add(selection);
            }
            return false;
        }

    }

    public boolean doUpdateNewNote(ZLTextView myView, BookReadNote note) {
        if (note == null) {
            return false;
        }
        synchronized (mViewNotes) {
            ZLTextSelection selection = new ZLTextSelection(myView, note);
            if (selection != null) {
                mViewNotes.remove(selection);
                return mViewNotes.add(selection);
            }
            return false;
        }
    }

    public boolean removeSelection(ZLTextSelection selection) {
        synchronized (mViewNotes) {
            if (selection != null && !selection.isEmpty()) {
                mViewNotes.remove(selection);
                return true;
            }
            return false;
        }
    }

    public void drawNoteFlag(ZLPaintContext context, ZLTextPage page, Chapter readingChapter) {
        if (readingChapter == null || TextUtils.isEmpty(readingChapter.getId())) {
            return;
        }
        synchronized (mViewNotes) {
            ZLTextSelection.Point rightPoint = null;
            for (ZLTextSelection node : mViewNotes) {
                INoteBean noteData = node.getNoteData();
                if (noteData != null && noteData instanceof BookReadNote && noteData.getChapterId() != null && noteData.getChapterId().equals(readingChapter.getId())) {
                    rightPoint = getSelectionCursorPoint(node, page,
                            SelectionCursor.Which.Right);
                    if (rightPoint != null) {
                        drawNoteFlag(context, node, rightPoint);
                    }
                }
            }
        }
    }

    private void drawNoteFlag(ZLPaintContext context, ZLTextSelection selection, ZLTextSelection.Point point) {
        if (point == null || selection == null) {
            return;
        }
        int cx = point.X, cy = point.Y;
        context.setFillColor(selection.getStyleColor());
        context.drawFilledCircle(cx, cy, 20);
        FBReaderApp fbReader = (FBReaderApp) FBReaderApp.Instance();

        bgColor = fbReader.getColorProfile().BackgroundOption.getValue();
        // 如果设置成为开灯状态
        if (!ReadStyle.isNight(ReadSettingUtil.getReadStyle())) {
            bgColor = new ZLColor(0x000000);
        }

        context.setFillColor(bgColor);
        context.drawFilledCircle(cx - 10, cy, 3);
        context.drawFilledCircle(cx, cy, 3);
        context.drawFilledCircle(cx + 10, cy, 3);
        selection.setNotePosition(point);
    }

    public void drawSelectionBackground(ZLTextView zlTextView, ZLTextPage page, ZLTextLineInfo info, int from, int to, int y, Chapter readingChapter) {
        if (readingChapter == null || TextUtils.isEmpty(readingChapter.getId())) {
            return;
        }
        synchronized (mViewNotes) {
            for (ZLTextSelection note : mViewNotes) {
                INoteBean noteData = note.getNoteData();
                if ((noteData != null && noteData.getChapterId() != null && readingChapter.getId().equals(noteData.getChapterId()))) {
                    zlTextView.drawSelectionBackground(note, null, page, info, from, to, y);
                }

            }
        }
    }

    public ZLTextSelection.Point getSelectionCursorPoint(ZLTextSelection section, ZLTextPage page, SelectionCursor.Which cursor) {
        if (section == null) {
            return null;
        }

        if (cursor == section.getCursorInMovement()) {
            return section.getCursorInMovementPoint();
        }

        if (cursor == SelectionCursor.Which.Left) {
            if (section.hasPartBeforePage(page)) {
                return null;
            }
            final ZLTextElementArea selectionStartArea = section.getStartArea(page);
            if (selectionStartArea != null) {
                return new ZLTextSelection.Point(selectionStartArea.XStart, selectionStartArea.YEnd);
            }
        } else {
            if (section.hasPartAfterPage(page)) {
                return null;
            }
            final ZLTextElementArea selectionEndArea = section.getEndArea(page);
            if (selectionEndArea != null) {
                return new ZLTextSelection.Point(selectionEndArea.XEnd, selectionEndArea.YEnd);
            }
        }
        return null;
    }

    public boolean gotoNoteInRead(ZLTextView view, int x, int y) {
        synchronized (mViewNotes) {
            boolean result = false;
            ZLTextSelection selectedNote = null;
            Object noteData;
            Pair<Integer, Integer> endXY;
            for (ZLTextSelection note : mViewNotes) {
                    noteData = note.getNoteData();
                    if (noteData != null && noteData instanceof BookReadNote) {
                        endXY = view.getSelectionEndXY(note);
                        if (Math.abs(endXY.first - x) <= 50 && Math.abs(endXY.second - y) <= 50) {
                            selectedNote = note;
                            break;
                        }
                    }

            }
            if (selectedNote != null
                    && selectedNote.getNoteData() != null
                    && selectedNote.getNoteData() instanceof BookReadNote) {
                ReadActivity readActivity = (ReadActivity) FBReaderApp.Instance().getAppContext();
                readActivity.gotoMyNoteList((BookReadNote) selectedNote.getNoteData());
                result = true;
            }
            return result;
        }
    }


    public void destroy() {
        mViewNotes.clear();
        mViewNotes = null;
        bgColor = null;
        sInstance = null;
    }
}
